package cn.dengta.context.model;

import javax.annotation.Nullable;

import cn.dengta.common.context.Env;
import cn.dengta.common.model.Bean;
import cn.dengta.context.auth.UserPermission;
import me.codeplayer.util.*;
import org.apache.commons.lang3.StringUtils;

public interface Member extends Bean<Long>, UserPermission {

	/**
	 * 是否有效
	 */
	default boolean isValid() {
		return canLogin() && !isFrozen();
	}

	/**
	 * 指示用户是否已被冻结（无法登录和操作）
	 */
	boolean isFrozen();

	/**
	 * 是否可登录
	 */
	boolean canLogin();

	/**
	 * 是否可后台登录
	 */
	boolean canLoginBackstage();

	/**
	 * 是否需要强制设置头像
	 */
	default boolean needSetAvatar() {
		return false;
	}

	/**
	 * 是否需要强制设置推广员
	 */
	default boolean needSetAgent() {
		return false;
	}

	/**
	 * 获取会话ID
	 */
	default String getSessionId() {
		return null;
	}

	void setSessionId(String sessionId);

	/**
	 * 指示用户已被注销
	 */
	boolean isDestroyed();

	String getUsername();

	Language getLanguage();

	String getPassword();

	/** 冻结提示（isFrozen = true获取） */
	FreezeTip getFreezeTip();

	default boolean isAdmin() {
		return false;
	}

	default boolean hasChangeLanguage() {
		return true;
	}

	long UID_OFFSET = 210321;

	/**
	 * 非生产环境请【不要】直接引用该常量
	 * 请使用如下方法替代：
	 *
	 * @see #idPrefix()
	 */
	static String idPrefix() {
		return WesKit.idPrefix(Env.CURRENT, null);
	}

	/** 生产环境/UAT专用的 ID 转换方法 */
	static long encodeValForProd(final long idVal) {
		int suffix = Long.hashCode(idVal) % 100;
		return (idVal + UID_OFFSET) * 100 + suffix;
	}

	static long decodeValForProd(final long encodedIdVal) {
		return encodedIdVal / 100 - UID_OFFSET;
	}

	static String encode(Long id) {
		return encode(id, WesKit.calcIdPrefix(id));
	}

	static String encodeNotPrefix(Long id) {
		final WesKit wesKit = WesKit.ofIdWesKit(id);
		if (wesKit.isMain()) {
			return encode(id);
		}
		return String.valueOf(id);
	}

	static String encode(Long id, String idPrefix) {
		if (id == null) {
			return null;
		}
		if (Env.inProduction()) { // uat分包前缀一致统一加密不区分。
			final WesKit wesKit = WesKit.ofIdWesKit(id);
			return (StringUtil.isEmpty(idPrefix) ? WesKit.calcIdPrefix(id) : idPrefix) + id;
		}
		return X.expectNotNull(idPrefix, idPrefix()) + id;
	}

	default String encodedId() {
		return encode(getId());
	}

	static Long decode(@Nullable String encodedId) {
		return decode(encodedId, true);
	}

	static Long decodeNotPrefix(@Nullable String encodedId) {
		if (StringUtils.isNumeric(encodedId)) {
			Long value = Long.valueOf(encodedId);
			if (value == 0) {
				return null;
			}
			if (!Env.inProduction()) {
				return value;
			}
			if (encodedId.length() > 7) {
				return value;
			}
		}
		return null;
	}

	/**
	 * 面向用户手动输入场景的外部 用户ID 解码方法。
	 *
	 * @param loosely 可选支持不区分大小写、自动去除两侧空格
	 */
	static Long decodeForInput(String encodedId, boolean loosely) {
		try {
			if (loosely) {
				encodedId = StringUtil.trim(encodedId).toLowerCase();
			}
			return decode(encodedId, false);
		} catch (NumberFormatException e) {
			return null;
		}
	}

	/**
	 * 兼容前缀与无前缀
	 * 面向用户手动输入场景的外部 用户ID 解码方法。
	 */
	static Long decodeForInputPrefix(String encodedId) {
		try {
			Long userId = decodeNotPrefix(encodedId);
			return userId == null ? decode(encodedId, false) : userId;
		} catch (NumberFormatException e) {
			return null;
		}
	}

	/**
	 * 面向用户手动输入场景的外部 用户ID 解码方法。支持不区分大小写、自动去除两侧空格。
	 */
	static Long decodeForInput(String encodedId) {
		return decodeForInput(encodedId, true);
	}

	static Long decode(@Nullable String encodedId, boolean fallback) {
		if (StringUtil.isEmpty(encodedId)) {
			return null;
		}
		if (Env.inProduction()) {
			if (WesKit.startsWith(encodedId)) {
				return Long.parseLong(StringUtils.substring(encodedId, 1));
			}
		} else if (WesKit.anyMatchPrefix(encodedId)) {
			return Long.parseLong(encodedId.substring(1));
		}
		return fallback ? Long.parseLong(encodedId) : null;
	}

}
